package com.york.tinyrpc.protoss.loadbalancer;

import com.york.tinyrpc.protoss.model.ServiceMetaInfo;

import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 静态加权轮询模式
 * 【静态】是因为权重信息是静态的，根据注册时指定
 * 根据服务器的性能或权重分配请求，性能更好的节点会获得更多的请求
 */
public class StaticWeightedRoundRobinLoadBalancer implements LoadBalancer {

    /**
     * 初始化当前轮询值，取模得到最终值
     */
    private final AtomicInteger currentCount = new AtomicInteger(0);

    /**
     * 获取目标服务
     *
     * @param requestParams 请求参数
     * @param serviceList   可选服务列表
     * @return
     */
    @Override
    public ServiceMetaInfo getTargetService(Map<String, Object> requestParams, List<ServiceMetaInfo> serviceList) {
        if (serviceList.isEmpty()) return null;

        // 静态计算总权重
        int totalWeight = serviceList.stream()
                .mapToInt(ServiceMetaInfo::getServiceWeight)
                .sum();

        // 获取当前轮询位置
        long mod = currentCount.getAndIncrement() % totalWeight;

        // 寻找目标节点
        int accumulated = 0;
        for (ServiceMetaInfo instance : serviceList) {
            accumulated += instance.getServiceWeight();
            if (mod < accumulated) {
                return instance;
            }
        }
        return serviceList.get(0);
    }
}